// patch.palette-optim.js — 去重 + 行为精简
(function(){
  'use strict';

  function rgbToHex(rgb){
    // "rgb(12, 34, 56)" -> "#0C2238"
    if(!rgb) return '';
    const m = rgb.trim().match(/^rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
    if(!m) return '';
    const r = Math.max(0, Math.min(255, parseInt(m[1],10)));
    const g = Math.max(0, Math.min(255, parseInt(m[2],10)));
    const b = Math.max(0, Math.min(255, parseInt(m[3],10)));
    const toHex = v => v.toString(16).padStart(2,'0').toUpperCase();
    return '#' + toHex(r) + toHex(g) + toHex(b);
  }

  function normHex(str){
    if(!str) return '';
    let s = String(str).trim();
    if(!s) return '';
    // Prefer explicit hex in attributes
    if(/^#([0-9a-f]{3,8})$/i.test(s)){
      s = s.toUpperCase();
      if(s.length===4){ s = '#' + s[1]+s[1] + s[2]+s[2] + s[3]+s[3]; }
      if(s.length===5){ s = s.slice(0,4); } // ignore alpha if #RGBA
      if(s.length===7 || s.length===9) return s.slice(0,7);
    }
    // Var or empty -> try computed background
    return '';
  }

  function readSwatchHex(el){
    // 1) attrs
    const attr = el.getAttribute('data-hex') || el.getAttribute('data-color') || el.getAttribute('data-swatch') || '';
    let hx = normHex(attr);
    if(hx) return hx;
    // 2) inline var(--sw) or style.background
    const inline = el.style.getPropertyValue('--sw') || el.style.background || '';
    hx = normHex(inline);
    if(hx) return hx;
    // 3) computed style
    try{
      const bg = getComputedStyle(el).backgroundColor;
      hx = rgbToHex(bg);
      if(hx) return hx;
    }catch(e){}
    return '';
  }

  function dedupe(container){
    const root = typeof container === 'string' ? document.querySelector(container) : container;
    if(!root) return;
    const seen = new Set();
    const items = Array.from(root.querySelectorAll('.swatch'));
    items.forEach(el=>{
      const hx = readSwatchHex(el);
      if(!hx) return;
      if(seen.has(hx)){
        // remove duplicates to avoid “重合”
        el.remove();
      }else{
        seen.add(hx);
      }
    });
  }

  function dedupeGeneric(container, itemSel){
    const root = typeof container === 'string' ? document.querySelector(container) : container;
    if(!root) return;
    const seen = new Set();
    Array.from(root.querySelectorAll(itemSel)).forEach(function(el){
      const hx = readSwatchHex(el);
      if(!hx) return;
      if(seen.has(hx)){ el.remove(); } else { seen.add(hx); }
    });
  }
  function run(){
    ['#color-search .cb-grid', '#color-board .cb-grid', '#tp-colorboard .cb-grid'].forEach(function(sel){ dedupeGeneric(sel, '.swatch'); });
    ['#color-search .swatches', '#cbx-swatches'].forEach(function(sel){ dedupeGeneric(sel, '.sw'); });
  }

  // Run after DOM ready & after late palette normalizers
  if(document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', run); }
  window.addEventListener('load', run);
  const mo = new MutationObserver(run);
  mo.observe(document.documentElement,{childList:true,subtree:true});
})();
